package com.asset.dispoal.business.make.service.commom;

import com.asset.dispoal.business.appoint.domain.db.mapper.AppointMapper;
import com.asset.dispoal.business.bsCase.domain.db.entity.CaseStateRecord;
import com.asset.dispoal.business.bsCase.domain.db.mapper.BsCaseMapper;
import com.asset.dispoal.business.make.domain.db.mapper.MakeMapper;
import com.asset.dispoal.business.make.dto.MakeReceiveCaseRequest;
import com.asset.dispoal.commom.menus.AgreementCaseSateMenu;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tech.mhuang.pacebox.core.date.DateTimeUtil;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.id.BaseIdeable;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.ObjectUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.protocol.Result;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MakeReceiveCaseCommand implements BaseCommand<MakeReceiveCaseRequest, Result> {

    @Autowired
    private AppointMapper appointMapper;
    @Autowired
    private MakeMapper makeMapper;

    @Autowired
    private BsCaseMapper caseMapper;

    @Autowired
    private BaseIdeable<String> ideable;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result execute(MakeReceiveCaseRequest request) {
        String userId = GlobalHeaderThreadLocal.getOrException().getUserId();
        //逻辑查询该批次下的所有当前状态的证据
        List<String> caseIdList = makeMapper.queryCaseIdByAppointIdState(request.getAppointId(),
                request.getState());
        if (CollectionUtil.isEmpty(caseIdList)) {
            return Result.faild("当前没有可处理的案件");
        }
        AgreementCaseSateMenu caseStateEnum = AgreementCaseSateMenu.getAddLabel(request.getState());

        if (AgreementCaseSateMenu.WAIT_UP_CASE.getLabel().equals(caseStateEnum.getLabel())) {
            Integer check = appointMapper.queryCountNumberByAppointIdNotState(request.getAppointId(),
                    AgreementCaseSateMenu.MAKING.getLabel());
            if (check > 0) {
                return Result.faild("当前存在不是制作中的案件");
            }
        } else {
            if ("1".equals(request.getType())) {
                //随机
                caseIdList = getRandomThreeInfoList(caseIdList, request.getRandomNum());
            } else if ("2".equals(request.getType())) {
                if (CollectionUtil.isEmpty(request.getCaseIdList())) {
                    return Result.faild("请选择案件");
                }
                //自选
                caseIdList = caseIdList.stream().filter(caseId -> request.getCaseIdList().contains(caseId)).collect(Collectors.toList());
            }
        }

        if (CollectionUtil.isEmpty(caseIdList)) {
            return Result.faild("找不到处理的案件");
        }

        for (String caseId : caseIdList) {
            CaseStateRecord caseStateRecord = new CaseStateRecord();
            caseStateRecord.setId(ideable.generateId());
            caseStateRecord.setOldState(request.getState());
            caseStateRecord.setNewState(caseStateEnum.getLabel());
            caseStateRecord.setCaseId(caseId);
            caseStateRecord.setCreateUser(userId);
            caseMapper.insertStateRecord(caseStateRecord);
            if (AgreementCaseSateMenu.MAKE.getLabel().equals(caseStateEnum.getLabel())) {
                caseMapper.updateCaseStateResv(caseId,
                        caseStateEnum.getLabel(),
                        caseStateEnum.getState(),
                        userId);
            } else {
                caseMapper.updateCaseState(caseId,
                        caseStateEnum.getLabel(),
                        caseStateEnum.getState(),
                        userId);
            }
        }
        if (ObjectUtil.isNotEmpty(request.getEvidenceAddress())) {
            appointMapper.updateAddress(request.getAppointId(),
                    request.getEvidenceAddress(),
                    caseIdList.size(), DateTimeUtil.currentDate());
        }
        if (ObjectUtil.isNotEmpty(request.getCalculationDate())) {
            appointMapper.updateSue(request.getAppointId(), request.getCalculationDate());
        }
        return Result.ok();
    }

    public static <T> List<T> getRandomThreeInfoList(List<T> list, int count) {
        if (list.size() <= count) {
            return list;
        } else {
            List<T> processList = new ArrayList<>(list);
            List<T> olist = new ArrayList<>(count);
            ThreadLocalRandom currentRandom = ThreadLocalRandom.current();
            for (int i = 0; i < count; i++) {
                int intRandom = currentRandom.nextInt(processList.size() - 1);
                olist.add(processList.get(intRandom));
                processList.remove(processList.get(intRandom));
            }
            return olist;
        }
    }
}
